using System;
using EPiServer.Common;
using EPiServer.Common.Queries;
using EPiServer.Common.Security;
using EPiServer.Community.Expert;
using EPiServer.Community.Expert.Queries;

namespace EPiAbstractions.Community.Expert
{
    public class ExpertHandlerFacade : IExpertHandlerFacade
    {
        private static ExpertHandlerFacade _instance;

        public ExpertHandlerFacade()
        {
            ExpertHandler.ExpertAdded += OnExpertAdded;
            ExpertHandler.ExpertUpdated += OnExpertUpdated;
            ExpertHandler.ExpertRemoved += OnExpertRemoved;
            ExpertHandler.AnswerAdded += OnAnswerAdded;
            ExpertHandler.AnswerUpdated += OnAnswerUpdated;
            ExpertHandler.AnswerRemoved += OnAnswerRemoved;
            ExpertHandler.QuestionAdded += OnQuestionAdded;
            ExpertHandler.QuestionUpdated += OnQuestionUpdated;
            ExpertHandler.QuestionRemoved += OnQuestionRemoved;
            ExpertHandler.QuestionStatusChanged += OnQuestionStatusChanged;
            ExpertHandler.AssignedQuestionAdded += OnAssignedQuestionAdded;
            ExpertHandler.AssignedQuestionRemoved += OnAssignedQuestionRemoved;
        }

        public static ExpertHandlerFacade Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new ExpertHandlerFacade();

                return _instance;
            }

            set { _instance = value; }
        }

        #region IExpertHandlerFacade Members

        public event EPiServerCommonEventHandler ExpertAdded;
        public event EPiServerCommonEventHandler ExpertUpdated;
        public event EPiServerCommonEventHandler ExpertRemoved;
        public event EPiServerCommonEventHandler AnswerAdded;
        public event EPiServerCommonEventHandler AnswerUpdated;
        public event EPiServerCommonEventHandler AnswerRemoved;
        public event EPiServerCommonEventHandler QuestionAdded;
        public event EPiServerCommonEventHandler QuestionUpdated;
        public event EPiServerCommonEventHandler QuestionRemoved;
        public event EPiServerCommonEventHandler QuestionStatusChanged;
        public event EPiServerCommonEventHandler AssignedQuestionAdded;
        public event EPiServerCommonEventHandler AssignedQuestionRemoved;

        public virtual ExpertBase AddExpert(ExpertBase expert)
        {
            return ExpertHandler.AddExpert(expert);
        }

        public virtual void UpdateExpert(ExpertBase expert)
        {
            ExpertHandler.UpdateExpert(expert);
        }

        public virtual void RemoveExpert(ExpertBase expert)
        {
            ExpertHandler.RemoveExpert(expert);
        }

        public virtual ExpertBase GetExpert(Int32 id)
        {
            return ExpertHandler.GetExpert(id);
        }

        public virtual ExpertBase GetExpert(Guid loginGuid)
        {
            return ExpertHandler.GetExpert(loginGuid);
        }

        public virtual ExpertBase GetExpert(IUser user)
        {
            return ExpertHandler.GetExpert(user);
        }

        public virtual ExpertCollection GetExperts(Int32 page, Int32 pageSize, ExpertSortOrder[] order)
        {
            return ExpertHandler.GetExperts(page, pageSize, order);
        }

        public virtual ExpertCollection GetExperts(SiteCollection sites, Int32 page, Int32 pageSize, ExpertSortOrder[] order)
        {
            return ExpertHandler.GetExperts(sites, page, pageSize, order);
        }

        public virtual ExpertCollection GetExperts(SiteCollection sites, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                   ExpertSortOrder[] order)
        {
            return ExpertHandler.GetExperts(sites, page, pageSize, out totalItems, order);
        }

        public virtual ExpertCollection GetExperts(SiteCollection sites, ExpertStatus expertStatus, Int32 page, Int32 pageSize,
                                                   ExpertSortOrder[] order)
        {
            return ExpertHandler.GetExperts(sites, expertStatus, page, pageSize, order);
        }

        public virtual ExpertCollection GetExperts(SiteCollection sites, ExpertStatus expertStatus, Int32 page, Int32 pageSize,
                                                   out Int32 totalItems, ExpertSortOrder[] order)
        {
            return ExpertHandler.GetExperts(sites, expertStatus, page, pageSize, out totalItems, order);
        }

        public virtual ExpertCollection GetExperts(SiteCollection sites, NullValueAction siteNullAction, ExpertStatus expertStatus,
                                                   Int32 page, Int32 pageSize, ExpertSortOrder[] order)
        {
            return ExpertHandler.GetExperts(sites, siteNullAction, expertStatus, page, pageSize, order);
        }

        public virtual ExpertCollection GetExperts(SiteCollection sites, NullValueAction siteNullAction, ExpertStatus expertStatus,
                                                   Int32 page, Int32 pageSize, out Int32 totalItems, ExpertSortOrder[] order)
        {
            return ExpertHandler.GetExperts(sites, siteNullAction, expertStatus, page, pageSize, out totalItems, order);
        }

        public virtual Question AddQuestion(Question question)
        {
            return ExpertHandler.AddQuestion(question);
        }

        public virtual void UpdateQuestion(Question question)
        {
            ExpertHandler.UpdateQuestion(question);
        }

        public virtual void RemoveQuestion(Question question)
        {
            ExpertHandler.RemoveQuestion(question);
        }

        public virtual Question GetQuestion(Int32 id)
        {
            return ExpertHandler.GetQuestion(id);
        }

        public virtual QuestionCollection GetQuestions(Int32 page, Int32 pageSize, QuestionSortOrder[] order)
        {
            return ExpertHandler.GetQuestions(page, pageSize, order);
        }

        public virtual QuestionCollection GetQuestions(Int32 page, Int32 pageSize, out Int32 totalItems, QuestionSortOrder[] order)
        {
            return ExpertHandler.GetQuestions(page, pageSize, out totalItems, order);
        }

        public virtual QuestionCollection GetQuestions(QuestionStatus questionStatus, Int32 page, Int32 pageSize, QuestionSortOrder[] order)
        {
            return ExpertHandler.GetQuestions(questionStatus, page, pageSize, order);
        }

        public virtual QuestionCollection GetQuestions(QuestionStatus questionStatus, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                       QuestionSortOrder[] order)
        {
            return ExpertHandler.GetQuestions(questionStatus, page, pageSize, out totalItems, order);
        }

        public virtual void AddQuestionRelation(Question question, Question relatedQuestion)
        {
            ExpertHandler.AddQuestionRelation(question, relatedQuestion);
        }

        public virtual void RemoveQuestionRelation(Question question, Question relatedQuestion)
        {
            ExpertHandler.RemoveQuestionRelation(question, relatedQuestion);
        }

        public virtual QuestionCollection GetRelatedQuestions(Question question)
        {
            return ExpertHandler.GetRelatedQuestions(question);
        }

        public virtual QuestionCollection GetRelatingQuestions(Question question)
        {
            return ExpertHandler.GetRelatingQuestions(question);
        }

        public virtual QuestionCollection GetNotRelatedQuestions(Question question, QuestionStatus status, Int32 page, Int32 pageSize,
                                                                 QuestionSortOrder[] order)
        {
            return ExpertHandler.GetNotRelatedQuestions(question, status, page, pageSize, order);
        }

        public virtual QuestionCollection GetNotRelatedQuestions(Question question, QuestionStatus status, Int32 page, Int32 pageSize,
                                                                 out Int32 totalItems, QuestionSortOrder[] order)
        {
            return ExpertHandler.GetNotRelatedQuestions(question, status, page, pageSize, out totalItems, order);
        }

        public virtual AssignedQuestion AddAssignedQuestion(AssignedQuestion assignedQuestion)
        {
            return ExpertHandler.AddAssignedQuestion(assignedQuestion);
        }

        public virtual void RemoveAssignedQuestion(AssignedQuestion assignedQuestion)
        {
            ExpertHandler.RemoveAssignedQuestion(assignedQuestion);
        }

        public virtual AssignedQuestion GetAssignedQuestion(Int32 id)
        {
            return ExpertHandler.GetAssignedQuestion(id);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestions(Question question, Int32 page, Int32 pageSize,
                                                                       ExpertSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestions(question, page, pageSize, order);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestions(Question question, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                                       ExpertSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestions(question, page, pageSize, out totalItems, order);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestions(ExpertBase expert, Int32 page, Int32 pageSize,
                                                                       QuestionSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestions(expert, page, pageSize, order);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestions(ExpertBase expert, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                                       QuestionSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestions(expert, page, pageSize, out totalItems, order);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestionsNotAnswered(Question question, Int32 page, Int32 pageSize,
                                                                                  ExpertSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestionsNotAnswered(question, page, pageSize, order);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestionsNotAnswered(Question question, Int32 page, Int32 pageSize,
                                                                                  out Int32 totalItems, ExpertSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestionsNotAnswered(question, page, pageSize, out totalItems, order);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestionsNotAnswered(ExpertBase expert, Int32 page, Int32 pageSize,
                                                                                  QuestionSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestionsNotAnswered(expert, page, pageSize, order);
        }

        public virtual AssignedQuestionCollection GetAssignedQuestionsNotAnswered(ExpertBase expert, Int32 page, Int32 pageSize,
                                                                                  out Int32 totalItems, QuestionSortOrder[] order)
        {
            return ExpertHandler.GetAssignedQuestionsNotAnswered(expert, page, pageSize, out totalItems, order);
        }

        public virtual Answer AddAnswer(Answer answer)
        {
            return ExpertHandler.AddAnswer(answer);
        }

        public virtual void UpdateAnswer(Answer answer)
        {
            ExpertHandler.UpdateAnswer(answer);
        }

        public virtual void RemoveAnswer(Answer answer)
        {
            ExpertHandler.RemoveAnswer(answer);
        }

        public virtual Answer GetAnswer(Int32 id)
        {
            return ExpertHandler.GetAnswer(id);
        }

        public virtual Answer GetAnswer(Question question, ExpertBase expert)
        {
            return ExpertHandler.GetAnswer(question, expert);
        }

        public virtual AnswerCollection GetAnswers(Question question, Int32 page, Int32 pageSize, AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(question, page, pageSize, order);
        }

        public virtual AnswerCollection GetAnswers(Question question, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                   AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(question, page, pageSize, out totalItems, order);
        }

        public virtual AnswerCollection GetAnswers(Question question, AnswerStatus answerStatus, Int32 page, Int32 pageSize,
                                                   AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(question, answerStatus, page, pageSize, order);
        }

        public virtual AnswerCollection GetAnswers(Question question, AnswerStatus answerStatus, Int32 page, Int32 pageSize,
                                                   out Int32 totalItems, AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(question, answerStatus, page, pageSize, out totalItems, order);
        }

        public virtual AnswerCollection GetAnswers(ExpertBase expert, Int32 page, Int32 pageSize, AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(expert, page, pageSize, order);
        }

        public virtual AnswerCollection GetAnswers(ExpertBase expert, Int32 page, Int32 pageSize, out Int32 totalItems,
                                                   AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(expert, page, pageSize, out totalItems, order);
        }

        public virtual AnswerCollection GetAnswers(ExpertBase expert, AnswerStatus answerStatus, Int32 page, Int32 pageSize,
                                                   AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(expert, answerStatus, page, pageSize, order);
        }

        public virtual AnswerCollection GetAnswers(ExpertBase expert, AnswerStatus answerStatus, Int32 page, Int32 pageSize,
                                                   out Int32 totalItems, AnswerSortOrder[] order)
        {
            return ExpertHandler.GetAnswers(expert, answerStatus, page, pageSize, out totalItems, order);
        }

        public virtual ExpertCollection GetQueryResult(ExpertQuery query)
        {
            return ExpertHandler.GetQueryResult(query);
        }

        public virtual ExpertCollection GetQueryResult(ExpertQuery query, Int32 page, Int32 pageSize)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize);
        }

        public virtual ExpertCollection GetQueryResult(ExpertQuery query, Int32 page, Int32 pageSize, out Int32 totalItems)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize, out totalItems);
        }

        public virtual QuestionCollection GetQueryResult(QuestionQuery query)
        {
            return ExpertHandler.GetQueryResult(query);
        }

        public virtual QuestionCollection GetQueryResult(QuestionQuery query, Int32 page, Int32 pageSize)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize);
        }

        public virtual QuestionCollection GetQueryResult(QuestionQuery query, Int32 page, Int32 pageSize, out Int32 totalItems)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize, out totalItems);
        }

        public virtual AssignedQuestionCollection GetQueryResult(AssignedQuestionQuery query)
        {
            return ExpertHandler.GetQueryResult(query);
        }

        public virtual AssignedQuestionCollection GetQueryResult(AssignedQuestionQuery query, Int32 page, Int32 pageSize)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize);
        }

        public virtual AssignedQuestionCollection GetQueryResult(AssignedQuestionQuery query, Int32 page, Int32 pageSize,
                                                                 out Int32 totalItems)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize, out totalItems);
        }

        public virtual AnswerCollection GetQueryResult(AnswerQuery query)
        {
            return ExpertHandler.GetQueryResult(query);
        }

        public virtual AnswerCollection GetQueryResult(AnswerQuery query, Int32 page, Int32 pageSize)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize);
        }

        public virtual AnswerCollection GetQueryResult(AnswerQuery query, Int32 page, Int32 pageSize, out Int32 totalItems)
        {
            return ExpertHandler.GetQueryResult(query, page, pageSize, out totalItems);
        }

        #endregion

        public virtual void OnExpertAdded(String sender, EPiServerCommonEventArgs e)
        {
            if (ExpertAdded != null)
                ExpertAdded(sender, e);
        }

        public virtual void OnExpertUpdated(String sender, EPiServerCommonEventArgs e)
        {
            if (ExpertUpdated != null)
                ExpertUpdated(sender, e);
        }

        public virtual void OnExpertRemoved(String sender, EPiServerCommonEventArgs e)
        {
            if (ExpertRemoved != null)
                ExpertRemoved(sender, e);
        }

        public virtual void OnAnswerAdded(String sender, EPiServerCommonEventArgs e)
        {
            if (AnswerAdded != null)
                AnswerAdded(sender, e);
        }

        public virtual void OnAnswerUpdated(String sender, EPiServerCommonEventArgs e)
        {
            if (AnswerUpdated != null)
                AnswerUpdated(sender, e);
        }

        public virtual void OnAnswerRemoved(String sender, EPiServerCommonEventArgs e)
        {
            if (AnswerRemoved != null)
                AnswerRemoved(sender, e);
        }

        public virtual void OnQuestionAdded(String sender, EPiServerCommonEventArgs e)
        {
            if (QuestionAdded != null)
                QuestionAdded(sender, e);
        }

        public virtual void OnQuestionUpdated(String sender, EPiServerCommonEventArgs e)
        {
            if (QuestionUpdated != null)
                QuestionUpdated(sender, e);
        }

        public virtual void OnQuestionRemoved(String sender, EPiServerCommonEventArgs e)
        {
            if (QuestionRemoved != null)
                QuestionRemoved(sender, e);
        }

        public virtual void OnQuestionStatusChanged(String sender, EPiServerCommonEventArgs e)
        {
            if (QuestionStatusChanged != null)
                QuestionStatusChanged(sender, e);
        }

        public virtual void OnAssignedQuestionAdded(String sender, EPiServerCommonEventArgs e)
        {
            if (AssignedQuestionAdded != null)
                AssignedQuestionAdded(sender, e);
        }

        public virtual void OnAssignedQuestionRemoved(String sender, EPiServerCommonEventArgs e)
        {
            if (AssignedQuestionRemoved != null)
                AssignedQuestionRemoved(sender, e);
        }
    }
}